home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / snurb / nurb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  6.1 KB  |  305 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* nurb.c */
  18.  
  19. #include <gl.h>
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include <malloc.h>
  23. #include "defines.h"
  24. #include <device.h>
  25. #include "event.h"
  26. #include "data.h"
  27. #include "draw.h"
  28. #include "matrix.h"
  29. #include "file.h"
  30. #include "control.h"
  31. #include "slider.h"
  32. #include "nurb.h"
  33.  
  34. static void update_childrens_control_points(
  35.     struct node_struct *child,
  36.     Matrix mat);
  37. static void transform_mesh(Mesh control, Matrix M);
  38.  
  39.  
  40. extern struct node_struct *root;
  41.  
  42.  
  43. /* Maximum size of nurbs polygon.
  44.    Increase for better speed, decrease for better display. */
  45. float pixel_tolerance=50.0;
  46.  
  47. /* Initializes the mesh to a plane with given z */
  48. void init_plane(Mesh control, Coord z)
  49. {
  50.     int s,t;
  51.     Coord x,spacing;
  52.  
  53.     spacing = 2.0/((float)(NUMPOINTS + 1));
  54.  
  55.     for(s = 0; s < NUMPOINTS; s++)
  56.     {
  57.         x = -1.0 + spacing;
  58.         for(t = 0; t < NUMPOINTS; t++)
  59.         {
  60.             control[s][t][0] = x;
  61.             control[t][s][1] = x;
  62.             control[s][t][2] = z;
  63.             x += spacing;
  64.         }
  65.     }
  66. }
  67.  
  68.  
  69. void draw_patch(Mesh control)
  70. {
  71.     static double s[NUMKNOTS] = 
  72.         {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
  73.  
  74.     static double t[NUMKNOTS] = 
  75.         {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
  76.  
  77.     double d_control[NUMPOINTS][NUMPOINTS][3];
  78.     int i,j,k;
  79.  
  80.     for(i = 0; i<NUMPOINTS; i++)
  81.         for(j = 0; j<NUMPOINTS; j++)
  82.             for(k=0; k<3; k++)
  83.                 d_control[i][j][k] = (double)control[i][j][k];
  84.  
  85.  
  86.     bgnsurface();
  87.     nurbssurface( 
  88.         sizeof(s) / sizeof(double), s, 
  89.         sizeof(t) / sizeof(double), t, 
  90.         3 * sizeof(double), 
  91.         NUMPOINTS * 3 * sizeof(double),    
  92.         (double *) d_control, 
  93.         ORDER, ORDER, 
  94.         N_XYZ
  95.         );
  96.     endsurface();
  97. }
  98.  
  99. void set_pixel_tolerance(void)
  100. {
  101.     draw_display();
  102. }
  103.  
  104. static long slider_window = -1;
  105. extern long snurb_window;
  106.  
  107.  
  108. static void close_slider_window(void)
  109. {
  110.     winset(slider_window);
  111.     winpush();
  112.     winset(snurb_window);
  113. }
  114.  
  115. void change_tolerance(void)
  116. {
  117.  
  118.     if (slider_window == -1)
  119.     {
  120.         keepaspect(8,1);
  121.          slider_window = winopen("sliderwin");
  122.         wintitle("Nurbs Resolution");
  123.     
  124.         RGBmode();
  125.         doublebuffer();
  126.         gconfig();
  127.  
  128.         add_slider("Maximum of %3.0f Pixels per Polygon", SLIDER_FLOAT, 1.0, 400.0,
  129.             (sliderval *)&pixel_tolerance, 0.0, 0.0, 1.0, 1.0, NULL);
  130.  
  131.         add_event(slider_window, LEFTMOUSE, UP, set_pixel_tolerance, NULL);
  132.     
  133.         add_event(ANY, WINSHUT, slider_window, close_slider_window, NULL);
  134.         /* WINSHUT queued in init_events */
  135.         winset(snurb_window);
  136.     }
  137.     else
  138.     {
  139.         winset(slider_window);
  140.         winpop();
  141.         winset(snurb_window);
  142.     }
  143. }
  144.  
  145. void add_primitive(int primitive)
  146. {
  147.     struct node_struct *new_object;
  148.  
  149.  
  150.     deselect_children(root->child);
  151.         
  152.     switch(primitive)
  153.     {
  154.         case PLANE:
  155.             read_file("plane.snb");
  156.             break;
  157.  
  158.         case CUBE:
  159.             read_file("cube.snb");
  160.             break;
  161.  
  162.         case TEAPOT:
  163.             read_file("teapot.snb");
  164.             break;
  165.  
  166.         default:
  167.             fprintf(stderr,"Uh Oh. Unknown primitive.\n");
  168.             exit(0);
  169.     }
  170.  
  171.     draw_display();
  172. }
  173.  
  174.  
  175.  
  176. static void update_childrens_control_points(
  177.     struct node_struct *child,
  178.     Matrix mat)
  179. {
  180.     if (child != NULL)
  181.     {
  182.         if (child->node_type == PATCH)
  183.             transform_mesh(child->patch->control, mat);
  184.             
  185.  
  186.         update_childrens_control_points(child->child, mat);
  187.         update_childrens_control_points(child->sibling, mat);
  188.     }
  189. }
  190.  
  191.  
  192. static void transform_mesh(Mesh control, Matrix M)
  193. {
  194.     int s,t;
  195.  
  196.     for (s=0; s<NUMPOINTS; s++)
  197.         for (t=0; t<NUMPOINTS; t++)
  198.             transform(control[s][t],M);
  199. }
  200.  
  201.  
  202. void update_control_points(
  203.     struct node_struct *object,
  204.     Matrix mat)
  205. {
  206.     if (object != NULL)
  207.     {
  208.         if (object->node_type == PATCH)
  209.             transform_mesh(object->patch->control, mat);
  210.  
  211.         
  212.         update_childrens_control_points(object->child, mat);
  213.     }
  214. }
  215.  
  216.  
  217.  
  218. void invert_selected_children(
  219.     struct node_struct *child,
  220.     Boolean parent_selected)
  221. {
  222.     int s,t,c,dest_edge,p;
  223.     Mesh temp;
  224.     Boolean child_selected;
  225.     struct node_struct *dest_patch;
  226.     struct zip_struct *zipper, *temp_zipper;
  227.     
  228.     if (child != NULL)
  229.     {
  230.         child_selected = (parent_selected || child->selected);
  231.  
  232.         if ((child->node_type == PATCH) && child_selected)
  233.         {
  234.  
  235.             /* Swap control points in s direction */
  236.             for (s=0; s<4; s++)
  237.                 for (t=0; t<4; t++)
  238.                     for (c=0; c<3; c++)
  239.                         temp[s][t][c] =    child->patch->control[s][t][c];
  240.                     
  241.             for (s=0; s<4; s++)
  242.                 for (t=0; t<4; t++)
  243.                     for (c=0; c<3; c++)
  244.                         child->patch->control[s][t][c] = temp[3-s][t][c];
  245.  
  246.             /* If it was zipped, swap s indexes and steps on all edges */
  247.             for (p=0; p<4; p++)
  248.                 if (child->patch->zipper[p]->zipped)
  249.                 {
  250.                     zipper = child->patch->zipper[p];
  251.  
  252.                     zipper->s_index = 3 - zipper->s_index;
  253.                     zipper->s_step = -1 * zipper->s_step;
  254.                     
  255.                     zipper->i_s_index = 3 - zipper->i_s_index;
  256.                     zipper->i_s_step = -1 * zipper->i_s_step;
  257.  
  258.                 }
  259.  
  260.  
  261.             if (child->patch->zipper[1]->zipped)
  262.             {
  263.                 dest_patch = child->patch->zipper[1]->patch;
  264.                 dest_edge = child->patch->zipper[1]->edge;
  265.  
  266.                 dest_patch->patch->zipper[dest_edge]->edge = 3;
  267.             }
  268.  
  269.             if (child->patch->zipper[3]->zipped)
  270.             {
  271.                 dest_patch = child->patch->zipper[3]->patch;
  272.                 dest_edge = child->patch->zipper[3]->edge;
  273.  
  274.                 dest_patch->patch->zipper[dest_edge]->edge = 1;
  275.             }
  276.                 
  277.             /* Swap what edges 1 and 3 were zipped to
  278.                 by swapping their zipper pointers */
  279.  
  280.             temp_zipper = child->patch->zipper[1];
  281.             child->patch->zipper[1] = child->patch->zipper[3];
  282.             child->patch->zipper[3] = temp_zipper;
  283.         }
  284.  
  285.         invert_selected_children(child->child, child_selected);
  286.         invert_selected_children(child->sibling, parent_selected);
  287.     }
  288. }
  289.  
  290.  
  291.     
  292.  
  293. /* Turns all selected objects inside out */
  294. void invert_objects(void)
  295. {
  296.     invert_selected_children(root->child,FALSE);
  297.  
  298.     draw_display();
  299. }
  300.  
  301.  
  302.  
  303.  
  304.  
  305.